// 1. 头文件包含
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_pwm.h"
#include "iot_adc.h"
#include "iot_errno.h"
#include "hi_time.h"
#include "oled.h"
#include "gui.h"

// 2. 宏定义
#define OLED_TASK_STACK_SIZE    4096
#define BUTTON_GPIO_PIN         5
#define LED_GPIO_PIN            6
#define BUZZER_PWM_GPIO         2
#define BUZZER_PWM_CH           2
#define SMOKE_ADC_GPIO          7
#define SMOKE_ADC_CHANNEL       3
#define ADC_VREF_VOL            1.8f
#define ADC_COEFFICIENT         4
#define ADC_RATIO               4096
#define SMOKE_VOLTAGE_THRESHOLD 0.6f // [修改] 将报警电压阈值修改为0.6V
#define BUZZER_ALARM_FREQ       4000
#define BUZZER_ALARM_COUNT      5
#define SENSOR_WARMUP_S         10
#define SNOOZE_DURATION_S       180

// 3. 全局状态变量
typedef enum {
    STATE_NORMAL,
    STATE_ALARM_ACTIVE,
    STATE_ALARM_SNOOZED
} SystemState;

static SystemState g_currentState = STATE_NORMAL;
static uint64_t g_snoozeStartTime = 0;

// 4. 驱动与功能函数

/**
 * @brief 读取烟雾传感器ADC值并转换为电压
 */
static float GetSmokeVoltage(void)
{
    unsigned short data;
    if (IoTAdcRead(SMOKE_ADC_CHANNEL, &data, IOT_ADC_EQU_MODEL_8, IOT_ADC_CUR_BAIS_DEFAULT, 0xff) == IOT_SUCCESS) {
        return (float)data * ADC_VREF_VOL * ADC_COEFFICIENT / ADC_RATIO;
    }
    printf("ADC Read Fail\n");
    return 0.0f;
}

/**
 * @brief 启动报警蜂鸣器
 */
void BuzzerWarning(int count)
{
    printf("BuzzerWarning Activated!\r\n");
    for (size_t i = 0; i < count; i++) {
        IoTPwmStart(BUZZER_PWM_CH, 50, BUZZER_ALARM_FREQ); // 50%占空比
        usleep(500000); // 鸣叫0.5秒
        IoTPwmStop(BUZZER_PWM_CH);
        usleep(200000); // 暂停0.2秒
    }
}

/**
 * @brief 按键中断服务函数
 */
static void ButtonPressedIsr(char *arg)
{
    (void)arg;
    if (g_currentState == STATE_ALARM_ACTIVE) {
        g_currentState = STATE_ALARM_SNOOZED;
        g_snoozeStartTime = hi_get_seconds();
        printf("Button pressed, alarm snoozed for %d seconds.\r\n", SNOOZE_DURATION_S);
    }
}

// 5. 主任务处理函数
void SmartGasAlarmTask(void * para)
{
    (void)para;

    // ---- 初始化所有硬件 ----
    OLED_Init();
    IoTGpioInit(LED_GPIO_PIN);
    IoTGpioSetDir(LED_GPIO_PIN, IOT_GPIO_DIR_OUT);
    IoTGpioSetOutputVal(LED_GPIO_PIN, IOT_GPIO_VALUE1);
    IoTGpioInit(BUTTON_GPIO_PIN);
    IoTGpioSetDir(BUTTON_GPIO_PIN, IOT_GPIO_DIR_IN);
    IoTGpioSetPull(BUTTON_GPIO_PIN, IOT_GPIO_PULL_UP);
    IoTGpioRegisterIsrFunc(BUTTON_GPIO_PIN, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, ButtonPressedIsr, NULL);
    IoTGpioInit(BUZZER_PWM_GPIO);
    IoTGpioSetFunc(BUZZER_PWM_GPIO, IOT_GPIO_FUNC_GPIO_2_PWM2_OUT);
    IoTGpioSetDir(BUZZER_PWM_GPIO, IOT_GPIO_DIR_OUT);
    IoTPwmInit(BUZZER_PWM_CH);
    IoTGpioSetPull(SMOKE_ADC_GPIO, IOT_GPIO_PULL_UP);

    printf("Smart Gas Alarm Initialized. Warming up sensor...\r\n");

    // 开机鸣叫提示，并等待传感器预热
    BuzzerWarning(3);
    for (int i = SENSOR_WARMUP_S; i > 0; i--) {
        OLED_Clear(0);
        char warmup_str[20] = {0};
        sprintf(warmup_str, "Warming up: %ds", i);
        GUI_ShowString(10, 20, (uint8_t*)warmup_str, 16, 1);
        OLED_Display();
        sleep(1);
    }
    
    printf("Starting main loop...\r\n");

    // ---- 主循环 ----
    float voltage = 0.0f;
    char voltage_str[20] = {0};

    while (1) {
        // 1. 读取传感器
        voltage = GetSmokeVoltage();
        
        // 2. 状态机逻辑
        switch (g_currentState) {
            case STATE_NORMAL:
                IoTGpioSetOutputVal(LED_GPIO_PIN, IOT_GPIO_VALUE1); // 确保LED在正常状态下是熄灭的
                if (voltage > SMOKE_VOLTAGE_THRESHOLD) {
                    g_currentState = STATE_ALARM_ACTIVE;
                }
                break;
            case STATE_ALARM_ACTIVE:
                // [修改] 在报警状态下，首先检查电压是否已恢复正常
                if (voltage <= SMOKE_VOLTAGE_THRESHOLD) {
                    g_currentState = STATE_NORMAL; // 如果恢复正常，则切换回正常状态
                    printf("Gas level is back to normal. Alarm stopped.\r\n");
                    break; // 跳出switch，在下一次循环中执行正常状态的逻辑
                }
                // 如果电压依然超标，则执行报警动作
                IoTGpioSetOutputVal(LED_GPIO_PIN, IOT_GPIO_VALUE0);
                BuzzerWarning(BUZZER_ALARM_COUNT);
                break;
            case STATE_ALARM_SNOOZED:
                IoTGpioSetOutputVal(LED_GPIO_PIN, IOT_GPIO_VALUE1); // 暂停时，LED熄灭
                if ((hi_get_seconds() - g_snoozeStartTime) > SNOOZE_DURATION_S) {
                    g_currentState = STATE_NORMAL;
                }
                break;
        }

        // 3. 更新OLED显示
        OLED_Clear(0);
        sprintf(voltage_str, "Gas: %.3fV", voltage);
        GUI_ShowString(0, 10, (uint8_t*)voltage_str, 16, 1);
        
        switch (g_currentState) {
            case STATE_ALARM_ACTIVE:
                GUI_ShowString(0, 30, (uint8_t*)"ALARM!", 16, 1);
                break;
            case STATE_ALARM_SNOOZED:
                GUI_ShowString(0, 30, (uint8_t*)"Snoozed...", 16, 1);
                break;
            case STATE_NORMAL:
            default:
                 GUI_ShowString(0, 30, (uint8_t*)"Normal", 16, 1);
                 break;
        }
        OLED_Display();

        // 4. 延时
        osDelay(1000);
    }
}

// 6. 启动函数
void SmartGasAlarmDemo(void)
{
    oled_gpio_io_init();
    screen_spi_master_init(0);

    osThreadAttr_t attr;
    attr.name = "SmartGasAlarmTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = OLED_TASK_STACK_SIZE;
    attr.priority = 20;

    if (osThreadNew((osThreadFunc_t)SmartGasAlarmTask, NULL, &attr) == NULL) {
        printf("[SmartGasAlarm] Falied to create SmartGasAlarmTask!\n");
    }
}

APP_FEATURE_INIT(SmartGasAlarmDemo);
